package co.edu.usbcali.unidades.dataaccess.dao;

import co.edu.usbcali.unidades.dataaccess.sessionFactory.HibernateSessionFactory;
import co.edu.usbcali.unidades.modelo.Persona;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.Session;

import org.hibernate.criterion.Example;

import java.math.BigDecimal;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;


/**
 * A data access object (DAO) providing persistence and search support for
 * Persona entities. Transaction control of the save(), update() and
 * delete() operations can directly support Spring container-managed
 * transactions or they can be augmented to handle user-managed Spring
 * transactions. Each of these methods provides additional information for how
 * to configure it for the desired type of transaction control.
 *
 *
 * @author Zathura Code Generator http://code.google.com/p/zathura
 *
 */
public class PersonaDAO implements IPersonaDAO {
    private static final Log log = LogFactory.getLog(PersonaDAO.class);

    // property constants
    //public static final String  PERCEDULA = "perCedula";
    public static final String PERCEDULA = "perCedula";

    //public static final String  PERCELULAR = "perCelular";
    public static final String PERCELULAR = "perCelular";

    //public static final String  PERCORREO = "perCorreo";
    public static final String PERCORREO = "perCorreo";

    //public static final String  PERPRIMERAPELLI = "perPrimerApelli";
    public static final String PERPRIMERAPELLI = "perPrimerApelli";

    //public static final String  PERPRIMERNOM = "perPrimerNom";
    public static final String PERPRIMERNOM = "perPrimerNom";

    //public static final String  PERSEGUNDOAPELLI = "perSegundoApelli";
    public static final String PERSEGUNDOAPELLI = "perSegundoApelli";

    //public static final String  PERSEGUNDONOM = "perSegundoNom";
    public static final String PERSEGUNDONOM = "perSegundoNom";

    //public static final String  PERTELEFONO = "perTelefono";
    public static final String PERTELEFONO = "perTelefono";

    private Session getSession() {
        return HibernateSessionFactory.getSession();
    }

    /**
    *
    * @param Instance
    *            Persona Instance to persist
    * @throws RuntimeException
    *             when the operation fails
    */
    public void save(Persona instance) {
        log.debug("saving Persona instance");

        try {
            getSession().save(instance);
            log.debug("save successful");
        } catch (RuntimeException re) {
            log.error("save failed", re);
            throw re;
        }
    }

    /**
    * @param Instance
    *            Persona Instance to delete
    * @throws RuntimeException
    *             when the operation fails
    */
    public void delete(Persona instance) {
        log.debug("deleting Persona instance");

        try {
            getSession().delete(instance);
            log.debug("delete successful");
        } catch (RuntimeException re) {
            log.error("delete failed", re);
            throw re;
        }
    }

    /**
    *
    * @param Instance
    *            Persona Instance to update
    * @throws RuntimeException
    *             when the operation fails
    */
    public void update(Persona instance) {
        log.debug("updating Persona instance");

        try {
            getSession().update(instance);
            log.debug("update successful");
        } catch (RuntimeException re) {
            log.error("update failed", re);
            throw re;
        }
    }
    public Persona findByIdTpDoc(String id,String tpDoc){
    	try {
    		List<Persona> per= new ArrayList<Persona>();
           String query="select p from Persona p where p.id=:ced and p.tipoDocumento.tipCodigoDoc=:doc";
           Query queryObject= getSession().createQuery(query);
           queryObject.setParameter("ced", id);
           queryObject.setParameter("doc", tpDoc);
           per=queryObject.list();
           if(per.size()==0){
        	   return null;
           }
           return per.get(0);
        } catch (RuntimeException re) {
            log.error("finding Persona failed", re);
            throw re;
        }
    }

    public Persona findById(String id) {
        log.debug("finding Persona instance with id: " + id);

        try {
            Persona instance = (Persona) getSession().get(Persona.class, id);

            return instance;
        } catch (RuntimeException re) {
            log.error("finding Persona failed", re);
            throw re;
        }
    }
    
    public Persona findPersona(String id,String tpPersona,String tpDoc) {
    	try {
    		List<Persona> per= new ArrayList<Persona>();
           String query="select p from Persona p where p.id=:ced and p.tipoDocumento.tipCodigoDoc=:doc and p.tipoPersona.tipNombreP=:tpPer";
           Query queryObject= getSession().createQuery(query);
           queryObject.setParameter("ced", id);
           queryObject.setParameter("doc", tpDoc);
           queryObject.setParameter("tpPer", tpPersona);
           per=queryObject.list();
           if(per.size()==0){
        	   return null;
           }
           return per.get(0);
        } catch (RuntimeException re) {
            log.error("finding Persona failed", re);
            throw re;
        }
    }

    public List<Persona> findByExample(Persona instance) {
        log.debug("finding Persona instance by example");

        try {
            List results = getSession().createCriteria("Persona")
                               .add(Example.create(instance)).list();
            log.debug("find by example successful, result size: " +
                results.size());

            return results;
        } catch (RuntimeException re) {
            log.error("find by example failed", re);
            throw re;
        }
    }

    /**
    * Find all  Persona entities with a specific property value.
    *
    * @param value
    *            the property value to match
    * @param propertyName
    *            the property to search in the instance
    * @return List< Persona> found by query
        */
    public List<Persona> findByProperty(String propertyName, Object value) {
        log.debug("finding Persona instance with property: " + propertyName +
            ", value: " + value);

        try {
            String queryString = "from Persona as model where model." +
                propertyName + "= ?";
            Query queryObject = getSession().createQuery(queryString);
            queryObject.setParameter(0, value);

            return queryObject.list();
        } catch (RuntimeException re) {
            log.error("find by property name failed", re);
            throw re;
        }
    }

    public List<Persona> findByPerCedula(Object perCedula) {
        return findByProperty(PERCEDULA, perCedula);
    }

    public List<Persona> findByPerCelular(Object perCelular) {
        return findByProperty(PERCELULAR, perCelular);
    }

    public List<Persona> findByPerCorreo(Object perCorreo) {
        return findByProperty(PERCORREO, perCorreo);
    }

    public List<Persona> findByPerPrimerApelli(Object perPrimerApelli) {
        return findByProperty(PERPRIMERAPELLI, perPrimerApelli);
    }

    public List<Persona> findByPerPrimerNom(Object perPrimerNom) {
        return findByProperty(PERPRIMERNOM, perPrimerNom);
    }

    public List<Persona> findByPerSegundoApelli(Object perSegundoApelli) {
        return findByProperty(PERSEGUNDOAPELLI, perSegundoApelli);
    }

    public List<Persona> findByPerSegundoNom(Object perSegundoNom) {
        return findByProperty(PERSEGUNDONOM, perSegundoNom);
    }

    public List<Persona> findByPerTelefono(Object perTelefono) {
        return findByProperty(PERTELEFONO, perTelefono);
    }

    /**
    * Find all Persona entities.
    *
    * @return List<Persona> all Persona instances
    */
    public List<Persona> findAll() {
        log.debug("finding all Persona instances");

        try {
            String queryString = "from Persona";
            Query queryObject = getSession().createQuery(queryString);

            return queryObject.list();
        } catch (RuntimeException re) {
            log.error("find all failed", re);
            throw re;
        }
    }
    
    public List<Persona> getAdminNombreParcial(Persona per){
    	List<Persona> admins = new ArrayList<Persona>();
    	try {
    		Query q = HibernateSessionFactory.getSession().createQuery("select p from Persona p where p.perPrimerNom like '%"+ per.getPerPrimerNom()+"%' and p.tipoPersona.tipCodigoP='5' and p.estado.estCodigo='1'");
        	admins=q.list();
        	if(admins.size()== 0){
        		return null;
        	}
        	
            return admins;
		} catch (RuntimeException re) {
			throw re;
		}
    }

    public List<Persona> findByCriteria(String whereCondition) {
        log.debug("finding Persona " + whereCondition);

        try {
            String where = ((whereCondition == null) ||
                (whereCondition.length() == 0)) ? "" : ("where " +
                whereCondition);
            final String queryString = "select model from Persona model " +
                where;
            Query query = getSession().createQuery(queryString);
            List<Persona> entitiesList = query.list();

            return entitiesList;
        } catch (RuntimeException re) {
            log.error("find By Criteria in Persona failed", re);
            throw re;
        }
    }

    public List<Persona> findPagePersona(String sortColumnName,
        boolean sortAscending, int startRow, int maxResults) {
        log.debug("finding Persona findPagePersona");

        if ((sortColumnName != null) && (sortColumnName.length() > 0)) {
            try {
                String queryString = "select model from Persona model order by model." +
                    sortColumnName + " " + (sortAscending ? "asc" : "desc");

                return getSession().createQuery(queryString)
                           .setFirstResult(startRow).setMaxResults(maxResults)
                           .list();
            } catch (RuntimeException re) {
                throw re;
            }
        } else {
            try {
                String queryString = "select model from Persona model";

                return getSession().createQuery(queryString)
                           .setFirstResult(startRow).setMaxResults(maxResults)
                           .list();
            } catch (RuntimeException re) {
                throw re;
            }
        }
    }

    public Long findTotalNumberPersona() {
        log.debug("finding Persona count");

        try {
            String queryString = "select count(*) from Persona model";
            Query queryObject = getSession().createQuery(queryString);

            return (Long) queryObject.list().get(0);
        } catch (RuntimeException re) {
            throw re;
        }
    }
}
